package persistencia;

import java.sql.Statement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import outros.Conexao;
import transporte.TOPatrimonio;
import outros.Util;
import principal.Principal;

public class DAOPatrimonio {
    private Conexao conexao = new Conexao();
    private Connection con = null;
    private Util util = new Util();

    public boolean abrirConexao() {
        UIManager.put("OptionPane.yesButtonText", "Sim");
        UIManager.put("OptionPane.noButtonText", "Não");
        UIManager.put("OptionPane.cancelButtonText", "Cancelar");
        try {
            conexao.abrirConexao();
            con = conexao.getConexao();
            return true;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro ao tentar conectar ao banco de dados.");
            return false;
        }
    }

    public String criar(TOPatrimonio patrimonio) {
        PreparedStatement ps = null;
        String sql = "INSERT INTO patri_patrimonio VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        try {
            abrirConexao();
            ps = con.prepareStatement(sql);
            int id = getProximo(patrimonio.getOrgao(), patrimonio.getArea(), patrimonio.getGrupo(), patrimonio.getSubgrupo());
            if (id!=0) {
                java.sql.Date data = null;
                ps.setInt(1, patrimonio.getArea());
                ps.setInt(2, patrimonio.getGrupo());
                ps.setInt(3, patrimonio.getSubgrupo());
                ps.setInt(4, id);
                ps.setString(5, patrimonio.getNome());
                try {
                    patrimonio.setDataEntrada(patrimonio.getDataEntrada().replaceAll("/", "-"));
                    data = java.sql.Date.valueOf(util.stringToData(patrimonio.getDataEntrada()));
                    ps.setDate(6, data);
                } catch (Exception e) {
                    ps.setDate(6, null);
                }
                ps.setInt(7, patrimonio.getBaixa());
                try {
                    patrimonio.setBaixaData(patrimonio.getBaixaData().replaceAll("/", "-"));
                    data = java.sql.Date.valueOf(util.stringToData(patrimonio.getBaixaData()));
                    ps.setDate(8, data);
                } catch (Exception e) {
                    ps.setDate(8, null);
                }
                ps.setInt(9, patrimonio.getBaixaTipo());
                ps.setInt(10, patrimonio.getSituacao());
                ps.setInt(11, patrimonio.getFornecedor());
                ps.setInt(12, patrimonio.getLotacao());                
                ps.setInt(13, patrimonio.getOrgao());                
                ps.setInt(14, patrimonio.getTipo());                
                ps.setInt(15, patrimonio.getAquisicao());
                ps.setDouble(16, util.monetarioToDouble(patrimonio.getValorMercReal()));
                ps.setDouble(17, util.monetarioToDouble(patrimonio.getValorMercDolar()));
                ps.setDouble(18, util.monetarioToDouble(patrimonio.getValorFinalReal()));
                ps.setDouble(19, util.monetarioToDouble(patrimonio.getValorFinalDolar()));
                ps.setInt(20, patrimonio.getNfNumero());
                try {
                    patrimonio.setNfData(patrimonio.getNfData().replaceAll("/", "-"));
                    data = java.sql.Date.valueOf(util.stringToData(patrimonio.getNfData()));
                    ps.setDate(21, data);
                } catch (Exception e) {
                    ps.setDate(21, null);
                }
                ps.setString(22, patrimonio.getProcesso());
                ps.setString(23, patrimonio.getChassi());
                ps.setString(24, patrimonio.getSerie());                
                ps.setInt(25, patrimonio.getPenhora());
                ps.setInt(26, patrimonio.getComodato());
                ps.setString(27, patrimonio.getObs());
                ps.setInt(28, patrimonio.getBloco());
                ps.setInt(29, patrimonio.getPagina());
                ps.setInt(30, patrimonio.getNumeroEstado());
                ps.execute();
                con.commit();
                conexao.fecharConexao();
                return "";
            } else {
                conexao.fecharConexao();
                JOptionPane.showMessageDialog(null, "Erro ao tentar atribuir novo ID.");
                return "erro";
            }
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar inserir dados. Detalhes: "+e.getMessage());
            return "erro";
        }
    }

    public TOPatrimonio selecionarRegistro(int area, int grupo, int subgrupo, int numero, int orgao, int setor) {
        Statement st = null;
        ResultSet rs = null;
        String sql = "";
        if (setor==-1) {
            sql = "SELECT * FROM patri_patrimonio WHERE area="+area+" AND grupo="+grupo+
                " AND subgrupo="+subgrupo+" AND numero="+numero+" AND orgao="+orgao;
        } else {
            sql = "SELECT * FROM patri_patrimonio WHERE area="+area+" AND grupo="+grupo+
                " AND subgrupo="+subgrupo+" AND numero="+numero+" AND orgao="+orgao+" AND lotacao="+setor;
        }
        try {
            abrirConexao();
            st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = st.executeQuery(sql);
            TOPatrimonio to;
            if (rs.first()) {
                to = new TOPatrimonio();
                to.setArea(rs.getInt("area"));
                to.setGrupo(rs.getInt("grupo"));
                to.setSubgrupo(rs.getInt("subgrupo"));
                to.setNumero(rs.getInt("numero"));
                to.setNome(rs.getString("nome"));
                to.setDataEntrada(rs.getString("data_entrada"));
                to.setBaixa(rs.getInt("baixa"));
                to.setBaixaData(rs.getString("baixa_data"));
                to.setBaixaTipo(rs.getInt("baixa_tipo"));
                to.setSituacao(rs.getInt("situacao"));
                to.setFornecedor(rs.getInt("fornecedor"));
                to.setLotacao(rs.getInt("lotacao"));
                to.setOrgao(rs.getInt("orgao"));
                to.setTipo(rs.getInt("tipo"));
                to.setAquisicao(rs.getInt("aquisicao"));
                NumberFormat dinheiro = new DecimalFormat("#,##0.00");
                to.setValorMercReal(dinheiro.format(rs.getDouble("valor_merc_real")));
                to.setValorMercDolar(dinheiro.format(rs.getDouble("valor_merc_dolar")));
                to.setValorFinalReal(dinheiro.format(rs.getDouble("valor_final_real")));
                to.setValorFinalDolar(dinheiro.format(rs.getDouble("valor_final_dolar")));
                to.setNfNumero(rs.getInt("NF_numero"));
                to.setNfData(rs.getString("NF_data"));
                to.setProcesso(rs.getString("processo"));
                to.setChassi(rs.getString("chassi"));
                to.setSerie(rs.getString("serie"));
                to.setPenhora(rs.getInt("penhora"));
                to.setComodato(rs.getInt("comodato"));
                to.setObs(rs.getString("obs"));                
                to.setBloco(rs.getInt("bloco"));
                to.setPagina(rs.getInt("pagina"));
                to.setNumeroEstado(rs.getInt("numero_estado"));
                to.setGarantia(rs.getInt("garantia"));
                to.setEmprestimo(rs.getInt("emprestimo"));
                return to;
            }
            conexao.fecharConexao();
            return null;
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar consultar dados. Detalhes: "+e.toString());
            return null;
        }
    }

    public ArrayList<TOPatrimonio> selecionarPorSetor(int setor) {
        Statement st = null;
        ResultSet rs = null;
        String sql = "";
        sql = "SELECT orgao,area,grupo,subgrupo,numero,nome,garantia,emprestimo FROM patri_patrimonio WHERE lotacao="+setor+" ORDER BY nome ASC";
        try {
            abrirConexao();
            st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = st.executeQuery(sql);
            ArrayList<TOPatrimonio> al;
            if (rs.first()) {
                al = new ArrayList();
                TOPatrimonio to = new TOPatrimonio();
                to.setOrgao(rs.getInt("orgao"));
                to.setArea(rs.getInt("area"));
                to.setGrupo(rs.getInt("grupo"));
                to.setSubgrupo(rs.getInt("subgrupo"));
                to.setNumero(rs.getInt("numero"));
                to.setNome(rs.getString("nome"));
                to.setGarantia(rs.getInt("garantia"));
                to.setEmprestimo(rs.getInt("emprestimo"));
                al.add(to);
                while (rs.next()) {
                    to = new TOPatrimonio();
                    to.setOrgao(rs.getInt("orgao"));
                    to.setArea(rs.getInt("area"));
                    to.setGrupo(rs.getInt("grupo"));
                    to.setSubgrupo(rs.getInt("subgrupo"));
                    to.setNumero(rs.getInt("numero"));
                    to.setNome(rs.getString("nome"));
                    to.setGarantia(rs.getInt("garantia"));
                    to.setEmprestimo(rs.getInt("emprestimo"));
                    al.add(to);
                }
                return al;
            }
            conexao.fecharConexao();
            return null;
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar consultar por setor. Detalhes: "+e.toString());
            return null;
        }
    }

    public ArrayList<TOPatrimonio> selecionar(Integer orgao, String area, String grupo, String subgrupo, String numero, String nome) {
        Statement st = null;
        ResultSet rs = null;
        String sql = "";
        if (area.length()==0 && grupo.length()==0 && subgrupo.length()==0 && numero.length()==0 && nome.length()==0) {
            sql = "SELECT area,grupo,subgrupo,numero,nome,orgao FROM patri_patrimonio";
            if (orgao!=null) {
                sql += " WHERE orgao="+orgao;
            }
        } else {
            sql = "SELECT area,grupo,subgrupo,numero,nome,orgao FROM patri_patrimonio WHERE sem_acento(nome) ILIKE '"+nome+"%'";
            if (orgao!=null) {
                sql += " AND orgao="+orgao;
            }
            if (area.length()>0) {
                sql += " AND area="+area;
            }
            if (grupo.length()>0) {
                sql += " AND grupo="+grupo;
            }
            if (subgrupo.length()>0) {
                sql += " AND subgrupo="+subgrupo;
            }
            if (numero.length()>0) {
                sql += " AND numero="+numero;
            }
        }
        sql += " ORDER BY nome ASC";
        try {
            abrirConexao();
            st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = st.executeQuery(sql);
            ArrayList<TOPatrimonio> al;
            if (rs.first()) {
                al = new ArrayList();
                TOPatrimonio to = new TOPatrimonio();
                to.setArea(rs.getInt("area"));
                to.setGrupo(rs.getInt("grupo"));
                to.setSubgrupo(rs.getInt("subgrupo"));
                to.setNumero(rs.getInt("numero"));
                to.setNome(rs.getString("nome"));
                to.setOrgao(rs.getInt("orgao"));
                al.add(to);
                while (rs.next()) {
                    to = new TOPatrimonio();
                    to.setArea(rs.getInt("area"));
                    to.setGrupo(rs.getInt("grupo"));
                    to.setSubgrupo(rs.getInt("subgrupo"));
                    to.setNumero(rs.getInt("numero"));
                    to.setNome(rs.getString("nome"));
                    to.setOrgao(rs.getInt("orgao"));
                    al.add(to);
                }
                return al;
            }
            conexao.fecharConexao();
            return null;
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar consultar dados. Detalhes: "+e.toString());
            return null;
        }
    }

    public String excluir(int numero) {
        PreparedStatement ps = null;
        String sql = "DELETE FROM patri_patrimonio WHERE numero=?";
        try {
            abrirConexao();
            ps = con.prepareStatement(sql);
            ps.setInt(1, numero);
            ps.execute();
            conexao.fecharConexao();
            return "";
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar excluír dados. Detalhes: "+e.toString());
            return "erro";
        }
    }

    public String alterar(TOPatrimonio p) {
        PreparedStatement ps = null;
        java.sql.Date data = null;
        try {
            p.setBaixaData(p.getBaixaData().replaceAll("/", "-"));
            data = java.sql.Date.valueOf(util.stringToData(p.getBaixaData()));
        } catch (Exception e) {}
        String sql = "UPDATE patri_patrimonio SET nome=?, "+
                     "situacao=?, baixa=?, "+
                     "baixa_data=?, baixa_tipo=?, "+
                     "lotacao=?, fornecedor=?,"+
                     "penhora=?, comodato=?, "+
                     "obs=?, nf_numero=?"+
                     " WHERE area=? AND grupo=? AND "+
                     "subgrupo=? AND numero=? AND "+
                     "orgao=?";
        try {
            abrirConexao();
            ps = con.prepareStatement(sql);
            ps.setString(1, p.getNome());
            ps.setInt(2, p.getSituacao());
            ps.setInt(3, p.getBaixa());
            ps.setDate(4, data);
            ps.setInt(5, p.getBaixaTipo());
            ps.setInt(6, p.getLotacao());
            ps.setInt(7, p.getFornecedor());
            ps.setInt(8, p.getPenhora());
            ps.setInt(9, p.getComodato());
            ps.setString(10, p.getObs());
            ps.setInt(11, p.getNfNumero());
            ps.setInt(12, p.getArea());
            ps.setInt(13, p.getGrupo());
            ps.setInt(14, p.getSubgrupo());
            ps.setInt(15, p.getNumero());
            ps.setInt(16, p.getOrgao());
            ps.execute();
            con.commit();
            conexao.fecharConexao();
            return "";
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar alterar dados. Detalhes: "+e.toString());
            return "erro";
        }
    }

    /*public String alterar(TOPatrimonio patrimonio) {
        PreparedStatement ps = null;
        java.sql.Date data = null;
        String sql = "UPDATE patri_patrimonio SET area=?," +
                     " nome=?, data_entrada=?, baixa=?, baixa_data=?," +
                     " baixa_tipo=?, situacao=?, fornecedor=?," +
                     " lotacao=?, orgao=?, tipo=?, aquisicao=?," +
                     " valor_merc_real=?, valor_merc_dolar=?," +
                     " valor_final_real=?, valor_final_dolar=?," +
                     " nf_numero=?, nf_data=?, processo=?, chassi=?," +
                     " serie=?, penhora=?, comodato=?, obs=?,"+
                     " bloco=?, pagina=?, numero_estado=? WHERE area=?" +
                     " AND grupo=? AND subgrupo=? AND numero=?";
        try {
            abrirConexao();
            ps = con.prepareStatement(sql);
            ps.setInt(1, patrimonio.getArea());
            ps.setString(2, patrimonio.getNome());
            try {
                patrimonio.setDataEntrada(patrimonio.getDataEntrada().replaceAll("/", "-"));
                data = java.sql.Date.valueOf(util.stringToData(patrimonio.getDataEntrada()));
                ps.setDate(3, data);
            } catch (Exception e) {
                ps.setDate(3, null);
            }
            ps.setInt(4, patrimonio.getBaixa());
            try {
                patrimonio.setBaixaData(patrimonio.getBaixaData().replaceAll("/", "-"));
                data = java.sql.Date.valueOf(util.stringToData(patrimonio.getBaixaData()));
                ps.setDate(5, data);
            } catch (Exception e) {
                ps.setDate(5, null);
            }
            ps.setInt(6, patrimonio.getBaixaTipo());
            ps.setInt(7, patrimonio.getSituacao());
            ps.setInt(8, patrimonio.getFornecedor());
            ps.setInt(9, patrimonio.getLotacao());
            ps.setInt(10, patrimonio.getOrgao());
            ps.setInt(11, patrimonio.getTipo());
            ps.setInt(12, patrimonio.getAquisicao());
            ps.setDouble(13, util.monetarioToDouble(patrimonio.getValorMercReal()));
            ps.setDouble(14, util.monetarioToDouble(patrimonio.getValorMercDolar()));
            ps.setDouble(15, util.monetarioToDouble(patrimonio.getValorFinalReal()));
            ps.setDouble(16, util.monetarioToDouble(patrimonio.getValorFinalDolar()));
            ps.setInt(17, patrimonio.getNfNumero());
            try {
                patrimonio.setNfData(patrimonio.getNfData().replaceAll("/", "-"));
                data = java.sql.Date.valueOf(util.stringToData(patrimonio.getNfData()));
                ps.setDate(18, data);
            } catch (Exception e) {
                ps.setDate(18, null);
            }
            ps.setString(19, patrimonio.getProcesso());
            ps.setString(20, patrimonio.getChassi());
            ps.setString(21, patrimonio.getSerie());
            ps.setInt(22, patrimonio.getPenhora());
            ps.setInt(23, patrimonio.getComodato());
            ps.setString(24, patrimonio.getObs());
            ps.setInt(25, patrimonio.getBloco());
            ps.setInt(26, patrimonio.getPagina());
            ps.setInt(27, patrimonio.getNumeroEstado());
            ps.setInt(28, patrimonio.getGrupo());
            ps.setInt(29, patrimonio.getGrupo());
            ps.setInt(30, patrimonio.getSubgrupo());
            ps.setInt(31, patrimonio.getNumero());
            System.out.println(ps.toString());
            ps.execute();
            con.commit();
            conexao.fecharConexao();
            return "";
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar alterar dados. Detalhes: "+e.toString());
            return "erro";
        }
    }*/

    public void criarRegistro(TOPatrimonio pat, String acao, int numero) {
        abrirConexao();
        int id = 0;
        try {
            id = getProximoIdRegistro();
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar atribuir ID do registro de patrimônio.");
            return;
        }
        PreparedStatement ps = null;
        String sql = "INSERT INTO patri_reg_patrimonio VALUES(?,?,?,?,?,?,?,?,?,?)";
        try {
            ps = con.prepareStatement(sql);
            ps.setInt(1, id);
            ps.setDate(2, new java.sql.Date(util.getData().getTime()));
            ps.setString(3, util.getHora());
            ps.setInt(4, Principal.getUsuarioLogado().getNumero());
            ps.setString(5, acao);
            ps.setInt(6, pat.getOrgao());
            ps.setInt(7, pat.getArea());
            ps.setInt(8, pat.getGrupo());
            ps.setInt(9, pat.getSubgrupo());
            ps.setInt(10, numero);
            ps.execute();
            con.commit();
            conexao.fecharConexao();
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar inserir registro de patrimônio. Detalhes: "+e.toString());
        }
    }

    private int getProximoIdRegistro(){
        String sql = "SELECT MAX(numero) FROM patri_reg_patrimonio";
        try {
            Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = st.executeQuery(sql);
            if (rs.first()){
                return rs.getInt(1)+1;
            } else {
                return 0;
            }
        } catch (Exception e){
            JOptionPane.showMessageDialog(null, "Erro [getProximo(int area, int grupo, int subgrupo)]: "+e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
            return 0;
        }
    }

    public String getProximo(String orgao, String area, String grupo, String subgrupo) {
        int o = Integer.parseInt(orgao);
        int a = Integer.parseInt(area);
        int g = Integer.parseInt(grupo);
        int s = Integer.parseInt(subgrupo);
        try {
            abrirConexao();
            int proximo = getProximo(o, a, g, s);
            conexao.fecharConexao();
            return Integer.toString(proximo);
        } catch (Exception e) {
            conexao.fecharConexao();
            JOptionPane.showMessageDialog(null, "Erro ao tentar resgatar próximo ID. Detalhes: "+e.toString());
            return "";
        }
    }

    private int getProximo(int orgao, int area, int grupo, int subgrupo){
        String sql = "SELECT MAX(numero) FROM patri_patrimonio WHERE orgao="+orgao+" AND area="+area+" AND grupo="+grupo+" AND subgrupo="+subgrupo;
        try {            
            Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = st.executeQuery(sql);
            if (rs.first()){                
                return rs.getInt(1)+1;
            } else {
                return 0;
            }
        } catch (Exception e){
            JOptionPane.showMessageDialog(null, "Erro [getProximo(int area, int grupo, int subgrupo)]: "+e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
            return 0;
        }
    }

    public boolean numeroExiste(int area, int grupo, int subgrupo, int numero) {
        String sql = "SELECT nome FROM patri_patrimonio WHERE area="+area+" AND grupo="+grupo+" AND subgrupo="+subgrupo+" AND numero="+numero;
        try {
            abrirConexao();
            Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = st.executeQuery(sql);
            if (rs.first()) {
                conexao.fecharConexao();
                return true;
            } else {
                conexao.fecharConexao();
                return false;
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro ao tentar verificar se o número de patrimônio existe. Detalhes: "+e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
            return true;
        }
    }
}
